/**
  ETFAna project, Anyang Normal University && IMP-CAS
  \class ETFVMEEvent
  \brief class for holding an event for VME daq
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2021-09-27
  \date 2021-09-28 last modified
  \attention
  changelog
  <table>
  <tr>  <th>Date        <th>Author      <th>Description                    </tr>
  <tr>  <td>2021-09-27   <td>Asia Sun    <td>file created                   </tr>
  </table>

  \copyright Copyright (c) 2021-2024 Anyang Normal U. && IMP-CAS with LGPLv3 LICENSE
*/

#include <TClonesArray.h>
#include "ETFVMEEvent.h"
#include "ETFHPTDCCh.h"
#include "ETFAmpCh.h"
#include "ETFVMERawEvent.h"
#include "ETFMsg.h"

ETFVMEEvent::ETFVMEEvent(int id) : fId(id),
fHPTDCChannels(new TClonesArray("ETFHPTDCCh")),
fAmplitudeChannels(new TClonesArray("ETFAmpCh")),
fRawEvent(new ETFVMERawEvent(id)){
  fSca.fill(0); fPSca.fill(0); fDSca.fill(0);
  Reset();
} // end ctor

ETFVMEEvent::ETFVMEEvent(const ETFVMEEvent &evt) : fId(evt.fId),
fBunchID(evt.fBunchID), fEventID(evt.fEventID), fSca(evt.fSca),
fPSca(evt.fPSca), fDSca(evt.fDSca), fEventHead(evt.fEventHead),
fHPTDCChannels(new TClonesArray(*evt.fHPTDCChannels)),
fAmplitudeChannels(new TClonesArray(*evt.fAmplitudeChannels)),
fRawEvent(evt.fRawEvent){}

ETFVMEEvent::~ETFVMEEvent(){
  if(fHPTDCChannels){
    fHPTDCChannels->Delete();
    delete fHPTDCChannels;
  } // end if
  if(fAmplitudeChannels){
    fAmplitudeChannels->Delete();
    delete fAmplitudeChannels;
  } // end if
  if(fRawEvent) delete fRawEvent;
} // end the destructor

void ETFVMEEvent::Reset(){
  fHPTDCChannels->Clear();
  fAmplitudeChannels->Clear();
  fEventHead.initialize();
  fBunchID = 0; fEventID = 0; fEvIndex = 0;
  // fRawEvent->Reset();
} // end member function Reset

TClonesArray *ETFVMEEvent::GetHPTDCChannels() const{
  if(!fHPTDCChannels)
    ETFMsg::Error("ETFVMEEvent", "GetHPTDCChannels: required pointer is null");
  return fHPTDCChannels;
} // end the member function GetHPTDCChannels

TClonesArray *ETFVMEEvent::GetAmplitudeChannels() const{
  if(!fAmplitudeChannels)
    ETFMsg::Error("ETFVMEEvent", "GetAmplitudeChannels: required pointer is null");
  return fAmplitudeChannels;
} // end the member function GetAmplitudeChannels

ETFHPTDCCh *ETFVMEEvent::GetTChByChId(int chid) const{
  for(TObject *p : *fHPTDCChannels){
    auto t = dynamic_cast<ETFHPTDCCh *>(p);
    if(t->chid() == chid) return t;
  } // end for
  return nullptr;
} // end member function GetTChByChId

bool ETFVMEEvent::HasTChId(int chid) const{
  for(const TObject *p : *fHPTDCChannels){
    auto t = dynamic_cast<const ETFHPTDCCh *>(p);
    if(t->chid() == chid) return true;
  } // end for
  return false;
} // end member function HasTChId

ETFAmpCh *ETFVMEEvent::GetAChByChId(int chid) const{
  for(TObject *p : *fAmplitudeChannels){
    auto t = dynamic_cast<ETFAmpCh *>(p);
    if(t->chid() == chid) return t;
  } // end for
  return nullptr;
} // end member function GetAChByChId

bool ETFVMEEvent::HasAChId(int chid) const{
  return GetAChByChId(chid);
} // end member function HasAChId

double ETFVMEEvent::timeL(int chid, int i) const{
  return GetTChByChId(chid)->tl();
} // end member function timeL
double ETFVMEEvent::timeT(int chid, int i) const{
  return GetTChByChId(chid)->tt();
} // end member function timeT

double ETFVMEEvent::amp(int chid) const{
  return GetAChByChId(chid)->value();
} // end member fucntion amp

void ETFVMEEvent::PrintBunchID() const{
  cout << "event: " << fEventHead.index;
  cout << "\tbunchID: " << fBunchID << endl;
} // end member function PrintBunchID
void ETFVMEEvent::PrintEventID() const{
  cout << "event: " << fEventHead.index;
  cout << "\tEventID: " << fEventID << endl;
} // end member function PrintEventID
void ETFVMEEvent::Print() const{
  fEventHead.print();
  cout << "BunchID: " << fBunchID << "\tEventID: " << fEventID << endl;

  cout << " ----------- SCA ------------" << endl;
  for(int j = 0; j < 16; j++){
    cout << "sca[" << j << "]: " << fSca[j];
    cout << "\tpsca[" << j << "]: " << fPSca[j];
    cout << "\tdsca[" << j << "]: " << fDSca[j] << endl;
  } // end for over i

  ETFRawChannel *ch;
  TIter nextT(fHPTDCChannels);
  TIter nextA(fAmplitudeChannels);
  // don't use bunchid for the relative time here. See the header file for detail
  while((ch = dynamic_cast<ETFRawChannel *>(nextT()))) ch->Print();
  while((ch = dynamic_cast<ETFRawChannel *>(nextA()))) ch->Print();

  cout << "tch_num: " << fHPTDCChannels->GetEntriesFast();
  cout << "\tach_num: " << fAmplitudeChannels->GetEntriesFast() << endl;
} // end member function Print
